#include <QtTest/QtTest>
#include "macroruletest.h"
#include "config/macrorule.h"

typedef QPair<int, int> Var;

MacroRuleTest::MacroRuleTest(QObject *parent) :
  QObject(parent)
  {
  }

void MacroRuleTest::initTestCase() { }

void MacroRuleTest::cleanupTestCase() { }

void MacroRuleTest::testGetNextCombination_data()
  {
  QTest::addColumn< QList<Var> >("vars");
  QTest::addColumn< QList<int> >("currentValues");
  QTest::addColumn< QList<int> >("result");

    {
    QList<Var> vars({Var(0,3), Var(0,2), Var(0,1)});
    QList<int> cv({0,0,0});
    QList<int> r({0,0,1});
    QTest::newRow("1") << vars << cv << r;
    }

    {
    QList<Var> vars({Var(0,3), Var(0,2), Var(0,1)});
    QList<int> cv({2,2,1});
    QList<int> r({3,0,0});
    QTest::newRow("2") << vars << cv << r;
    }

    {
    QList<Var> vars({Var(0,3), Var(0,2), Var(0,1)});
    QList<int> cv({3,2,1});
    QList<int> r({0,0,0});
    QTest::newRow("3") << vars << cv << r;
    }

    {
    QList<Var> vars({Var(0,3), Var(0,2), Var(0,1)});
    QList<int> cv({0,0,1});
    QList<int> r({0,1,0});
    QTest::newRow("4") << vars << cv << r;
    }

    {
    QList<Var> vars({Var(0,2)});
    QList<int> cv({1});
    QList<int> r({2});
    QTest::newRow("5") << vars << cv << r;
    }
  }

void MacroRuleTest::testGetNextCombination()
  {
  QFETCH(QList<Var>, vars);
  QFETCH(QList<int>, currentValues);
  QFETCH(QList<int>, result);
  MacroRule mr(Expression(), Expression(), "", MacroRule::MO_SUM,
               QList<MacroVariable>(), translator);

  QList<int> nextCombination = mr.getNextCombination(vars, currentValues);
  QCOMPARE(nextCombination, result);
  }

typedef QList<QPair<QString, QString>> StringPairList;

void MacroRuleTest::testGenerateRules_data()
  {
  QTest::addColumn<QString>("pattern");
  QTest::addColumn<QString>("macroReplacement");
  QTest::addColumn<StringPairList>("vars");
  QTest::addColumn<QString>("sExp");
  QTest::addColumn<int>("rulesCount");

  QTest::newRow("1") << "a_%1 b_%2" << "delta(%1.%i, %2.%i)" << StringPairList({QPair<QString, QString>("0","%1.size-1")}) <<
                        "a_x b_y" << 1;
  QTest::newRow("2") << "a_%1 b_%2" << "delta(%1.%i, %2.%i)" << StringPairList({QPair<QString, QString>("0","%1.size-1")}) <<
                        "a_{m n o} b_{x y z}" << 3;
  QTest::newRow("3") << "a_%1 b_%2" << "delta(%1.%i, %2.%j)" << StringPairList({QPair<QString, QString>("0","%1.size-1"),
                                                                                QPair<QString, QString>("0","%1.size-1")}) <<
                        "a_{m n o} b_{x y z}" << 9;

  }

void MacroRuleTest::testGenerateRules()
  {
  QFETCH(QString, pattern);
  QFETCH(QString, macroReplacement);
  QFETCH(StringPairList, vars);
  QFETCH(QString, sExp);
  QFETCH(int, rulesCount);

  Expression ePattern, exp;
  translator.stringToExp(pattern, ePattern);
  translator.stringToExp(sExp, exp);
  QList<MacroVariable> macroVars;
  for (int i = 0; i < vars.size(); i++)
    {
    QString name = "%";
    name.append(((int)'i' + i));
    macroVars.append(MacroVariable(name, vars[i].first,
                                   vars[i].second));
    }

  MacroRule mr(ePattern, Expression(), macroReplacement, MacroRule::MO_SUM,
               macroVars, translator);

  QList<Rule> rules = mr.generateRules(exp);
  QCOMPARE(rules.size(), rulesCount);
  }
